commonlibsse_ng\re\m\MemoryManager\alloc/
scrap_alloc.rs

1//! Scrap heap allocation rust like API(But for reasons of scrap heap reuse, it is a little different)
2use core::alloc::Layout;
3use core::ptr::NonNull;
4
5use crate::re::MemoryManager::MemoryManager;
6use crate::re::ScrapHeap::ScrapHeap;
7use stdx::alloc::AllocError;
8
9/// Attempts to allocate memory using the thread-local scrap heap managed by the custom memory system.
10///
11/// # Errors
12/// Returns a pair of non-null pointers to the scrap heap and the allocated memory on success, or an `AllocError` if allocation fails.
13///
14/// # Safety
15///
16/// - The returned memory is uninitialized.
17/// - The caller must ensure proper usage and deallocation of the returned pointer.
18#[inline]
19pub unsafe fn alloc(layout: Layout) -> Result<(NonNull<ScrapHeap>, NonNull<u8>), AllocError> {
20    unsafe {
21        let mem_manager = MemoryManager::GetSingleton().as_mut().ok_or(AllocError)?;
22
23        let scrap_heap = mem_manager.GetThreadScrapHeap().as_mut().ok_or(AllocError)?;
24        let ptr = scrap_heap.allocate(layout.size(), layout.align()).cast::<u8>();
25
26        NonNull::new(ptr).map(|nn_ptr| (NonNull::from(scrap_heap), nn_ptr)).ok_or(AllocError)
27    }
28}
29
30/// Attempts to allocate zero-initialized memory using the thread-local scrap heap.
31///
32/// # Errors
33/// Returns a pair of non-null pointers to the scrap heap and the allocated memory on success, or an `AllocError` if allocation fails.
34///
35/// # Safety
36///
37/// - The caller must ensure proper usage and deallocation of the returned pointer.
38/// - This function may write zero bytes to uninitialized memory.
39#[inline]
40pub unsafe fn alloc_zeroed(
41    layout: Layout,
42) -> Result<(NonNull<ScrapHeap>, NonNull<u8>), AllocError> {
43    unsafe {
44        let (scrap_heap, ptr) = alloc(layout)?;
45        ptr.as_ptr().write_bytes(0, layout.size());
46        Ok((scrap_heap, ptr))
47    }
48}
49
50/// Attempts to reallocate memory previously allocated from a thread-local scrap heap.
51///
52/// # Errors
53/// Returns a pair of non-null pointers to the scrap heap and the newly allocated memory on success,
54/// or an `AllocError` if reallocation fails.
55///
56/// The old memory region is not automatically copied or deallocated.
57///
58/// # Safety
59///
60/// - `old_ptr` must be a pointer previously returned by [`alloc`] or [`alloc_zeroed`] using the same scrap heap and layout.
61/// - The caller is responsible for copying any existing data and deallocating the old pointer if needed.
62/// - The returned memory is uninitialized.
63///
64/// This function behaves more like a fresh allocation than a standard realloc.
65#[inline]
66pub unsafe fn realloc(
67    mut scrap_heap: NonNull<ScrapHeap>,
68    new_layout: Layout,
69) -> Result<(NonNull<ScrapHeap>, NonNull<u8>), AllocError> {
70    unsafe {
71        let scrap_heap_ref = scrap_heap.as_mut();
72        let new_ptr = scrap_heap_ref.allocate(new_layout.size(), new_layout.align()).cast::<u8>();
73
74        NonNull::new(new_ptr).map(|nn_ptr| (scrap_heap, nn_ptr)).ok_or(AllocError)
75    }
76}
77
78/// Deallocates memory previously allocated using [`alloc`] or [`alloc_zeroed`] with the same scrap heap.
79///
80/// # Safety
81///
82/// - `ptr` must have been returned by a previous call to [`alloc`] or [`alloc_zeroed`] with the same layout and scrap heap.
83/// - Using an invalid pointer or mismatched layout may cause undefined behavior.
84#[inline]
85pub unsafe fn dealloc(mut scrap_heap: NonNull<ScrapHeap>, ptr: NonNull<u8>, layout: Layout) {
86    let _ = layout;
87    unsafe {
88        let scrap_heap = scrap_heap.as_mut();
89        let _ = scrap_heap.deallocate(ptr.cast().as_ptr());
90    }
91}